package com.project.poetry.common.util;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.project.poetry.common.exception.ServiceException;

import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 文件工具类
 * @author mengxj
 */
public final class FileUtil {

    private FileUtil(){}

    /**
     * 初始化pdf表头
     * @param table 表
     * @param font 字体
     * @param title 表头数组
     */
    public static void initPdfTableTitle(PdfPTable table, Font font, String[] title){
        for(String t: title){
            table.addCell(getCell(t, font));
        }
    }

    /**
     * 获取pdf单元格
     * @param value 单元格内容
     * @param font 字体
     * @return 单元格
     */
    public static PdfPCell getCell(String value, Font font){
        return getCell(value, font, 1);
    }

    /**
     * 获取带有隐藏边框的pdf单元格
     * @param value 单元格内容
     * @param font 字体
     * @param rowSpan 跨行数
     * @param colSpan 跨列数
     * @param side 隐藏边框   隐藏值   怎么记
     *                 上        1        2^0
     *                 下        2        2^1
     *                 左        4        2^2
     *                 右        8        2^3
     *              使用方法：想隐藏上下就传入3（1+2），想隐藏上下左
     *              传入7（1+2+4），以此类推
     * @return 单元格
     */
    public static PdfPCell getBorderStyleCell(String value, Font font, int rowSpan, int colSpan, int side){
        PdfPCell cell = getCell(value, font, rowSpan, colSpan);
        cell.disableBorderSide(side);
        return cell;
    }

    /**
     * 获取跨行pdf单元格
     * @param value 单元格内容
     * @param font 字体
     * @param rowSpan 跨行数
     * @return 单元格
     */
    public static PdfPCell getCell(String value, Font font, int rowSpan){
        return getCell(value, font, rowSpan, 1);
    }

    /**
     * 获取跨行pdf单元格
     * @param value 单元格内容
     * @param font 字体
     * @param rowSpan 跨行数
     * @param colSpan 跨列数
     * @return 单元格
     */
    public static PdfPCell getCell(String value, Font font, int rowSpan, int colSpan){
        PdfPCell cell = new PdfPCell(new Phrase(value, font));
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setRowspan(rowSpan);
        cell.setColspan(colSpan);
        return cell;
    }

    /**
     * 设置并锁定pdf文件中表宽度
     * @param table 表
     */
    public static void setTableLockedAndCenter(PdfPTable table){
        table.setTotalWidth(780);
        table.setLockedWidth(true);
        table.setHorizontalAlignment(Element.ALIGN_CENTER);
    }

    /**
     * 添加pdf文档标题
     * @param document 文档
     * @param bfChinese 字体
     * @param titleLine 标题内容
     * @throws DocumentException 添加标题时产生的异常
     */
    public static void addDocumentTitle(Document document, BaseFont bfChinese, String titleLine) throws DocumentException {
        Paragraph title = new Paragraph(titleLine, new Font(bfChinese, 20, Font.NORMAL, BaseColor.BLACK));
        title.setAlignment(Element.ALIGN_CENTER);
        title.setSpacingAfter(10);
        title.setSpacingBefore(5);
        document.add(title);
    }

    /**
     * 给pdf文件添加水印
     * @param writer pdf输出流对象
     * @param text 水印文本
     */
    public static void addWaterDocument(PdfWriter writer, String text) {
        writer.setPageEvent(new Event(text));
    }

    /**
     * 事件对象
     */
    static class Event extends PdfPageEventHelper {
        private String text;
        public Event(String text) {
            this.text = text;
        }
        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            try{
                float pageWidth = document.right() + document.left();
                float pageHeight = document.top() + document.bottom();
                PdfContentByte waterMarkPdfContent = writer.getDirectContentUnder();
                BaseFont bf = BaseFont.createFont("STSong-Light",
                        "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                Font water = new Font(bf);
                water.setColor(new BaseColor(240, 240, 245));
                water.setSize(50);
                Phrase phrase = new Phrase(text, water);
                ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,pageWidth * 2 / 7, pageHeight * 2 / 5, 45);
                ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,pageWidth * 4 / 7, pageHeight * 2 / 5, 45);
                ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,pageWidth * 6 / 7, pageHeight * 2 / 5, 45);
                ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,pageWidth * 2 / 7, pageHeight * 4 / 5, 45);
                ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,pageWidth * 4 / 7, pageHeight * 4 / 5, 45);
                ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,pageWidth * 6 / 7, pageHeight * 4 / 5, 45);
            }catch (Exception e){
                throw new ServiceException(e.getMessage());
            }
        }
    }

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd/");

    /**
     * 获取文件名带有日期格式的真实文件名，
     * 如 a.txt --> 2021/09/10/a.txt
     * @param fileName 文件名
     * @return 日期格式文件名
     */
    public static String getRealFileName(String fileName){
        fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
        return FORMATTER.format(LocalDateTime.now()) + fileName;
    }

    /**
     * 校验文件夹是否存在，不存在则创建文件夹
     * @param filePath 文件路径
     */
    public static void checkAndCreateDir(String filePath) {
        String rootDir = filePath.substring(0, filePath.lastIndexOf("/"));
        File dir = new File(rootDir);
        if(!dir.exists() && !dir.mkdirs()){
            throw new ServiceException("保存文件时创建文件夹失败！");
        }
    }
}
